import asyncio
import aio_pika

from config import RABBITMQ_URI


async def setup_topic_exchange(exchange_name="demo.topic", queue_prefix="demo.topic.queue-"):
    """设置Topic类型交换器并绑定队列（支持通配符路由）"""
    # 建立连接
    connection = await aio_pika.connect_robust(RABBITMQ_URI)
    channel = await connection.channel()

    # 1. 声明Topic类型交换器
    topic_exchange = await channel.declare_exchange(
        exchange_name,
        aio_pika.ExchangeType.TOPIC,
        durable=True  # 交换器持久化
    )

    # 2. 定义队列及对应的绑定键（Topic交换器支持通配符）
    # 格式: (队列名称, 绑定键列表)
    # 通配符规则:
    # * 匹配恰好1个层级
    # # 匹配0个或多个层级（层级用.分隔）
    queue_bindings = [
        (f"{queue_prefix}critical", ["#.critical"]),  # 匹配任意前缀+critical
        (f"{queue_prefix}order", ["order.#"]),  # 匹配所有order开头的路由键
        (f"{queue_prefix}user.login", ["user.login.*"])  # 匹配user.login+1个后缀
    ]

    # 3. 循环创建队列并绑定到交换器
    for queue_name, binding_keys in queue_bindings:
        # 声明队列（持久化）
        queue = await channel.declare_queue(
            queue_name,
            durable=True,
            auto_delete=False
        )
        # 绑定多个通配符路由键到同一个队列
        for binding_key in binding_keys:
            await queue.bind(
                topic_exchange,
                routing_key=binding_key  # Topic交换器使用带通配符的绑定键
            )
        print(f"Queue {queue_name} bound to routing keys: {binding_keys}")

    await connection.close()


async def topic_publish(message: str, routing_key: str, exchange_name: str = "demo.topic"):
    """向Topic交换器发送消息（使用层级化路由键）"""
    # 建立连接
    connection = await aio_pika.connect_robust(RABBITMQ_URI)
    channel = await connection.channel()

    # 声明交换器（确保交换器存在）
    exchange = await channel.declare_exchange(
        exchange_name,
        aio_pika.ExchangeType.TOPIC,
        durable=True
    )

    # 构建消息对象（持久化）
    message_obj = aio_pika.Message(
        body=message.encode("utf-8"),
        delivery_mode=aio_pika.DeliveryMode.PERSISTENT
    )

    # 发送消息（指定层级化路由键，Topic交换器会按通配符匹配队列）
    await exchange.publish(
        message_obj,
        routing_key=routing_key  # 路由键为层级化字符串（如"order.create.user"）
    )
    print(f"Message sent: {message} (routing key: {routing_key})")

    await connection.close()
